package com.cyy.springbootinit.job.cycle;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cyy.springbootinit.constant.EquipmentNameConst;
import com.cyy.springbootinit.mapper.EquipmentInfoMapper;
import com.cyy.springbootinit.mapper.ReadingHistoryMapper;
import com.cyy.springbootinit.model.entity.*;
import com.cyy.springbootinit.model.enums.EquipmentTypeConst;
import com.cyy.springbootinit.model.vo.EleFeeRuleResponseVo;
import com.cyy.springbootinit.model.vo.EquipmentDataVO;
import com.cyy.springbootinit.model.vo.EquipmentInfoAllVO;
import com.cyy.springbootinit.model.vo.WaterFeeRuleResponseVo;
import com.cyy.springbootinit.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.stream.Collectors;

@Component
@Slf4j
@RequiredArgsConstructor
public class UpEquipmentData {
    private final EquipmentDataService equipmentDataService;
    private final ReadingHistoryMapper readingHistoryMapper;
    private final WaterFeeRuleService waterFeeRuleService;
    private final EleFeeRuleService eleFeeRuleService;
    private final EquipmentInfoMapper equipmentInfoMapper;
    private final DormitoryExpenseBillService dormitoryExpenseBillService;
    private final BalanceWarningService balanceWarningService;
    private final BalanceAlarmService balanceAlarmService;
    @Scheduled(cron = "59 59 23 L * ?")
    public void updateEquipmentDataReadValue() {
        log.info("新增月末账单");
        List<EquipmentInfoAllVO> equipmentInfoAllVOS=equipmentInfoMapper.getEquipmentInfoAll();
        // 使用Java 8 Stream API将列表转换为Map
        Map<Integer, List<EquipmentInfoAllVO>> equipmentInfoMap = equipmentInfoAllVOS.stream()
                .filter(info -> info.getDormitoryId() != null)  // 过滤掉dormitoryId为空的记录
                .collect(Collectors.groupingBy(
                        EquipmentInfoAllVO::getDormitoryId,  // key是dormitoryId
                        Collectors.toList()  // value是List<EquipmentInfoAllVO>
                ));
        List<DormitoryExpenseBill> dormitoryExpenseBills = new ArrayList<>();
        //遍历map生成账单
        for(Map.Entry<Integer, List<EquipmentInfoAllVO>> entry : equipmentInfoMap.entrySet()) {
            DormitoryExpenseBill dormitoryExpenseBill=new DormitoryExpenseBill();
            Integer dormitoryId = entry.getKey();
            dormitoryExpenseBill.setDormitoryId(dormitoryId);
            List<EquipmentInfoAllVO> equipmentInfoAllVOS1 = entry.getValue();
            for (EquipmentInfoAllVO equipmentInfoAllVO : equipmentInfoAllVOS1) {
                if (Objects.equals(equipmentInfoAllVO.getTypeName(), EquipmentTypeConst.WaterEquipment.getValue())) {
                    //获取水费
                    WaterFeeRuleResponseVo waterFeeRuleResponseVo = waterFeeRuleService.calculateOrderFee(equipmentInfoAllVO.getReadingValue() - equipmentInfoAllVO.getReadValue());
                    Double totalAmount = waterFeeRuleResponseVo.getTotalAmount();
                    dormitoryExpenseBill.setWaterExpense(totalAmount);
                } else if (Objects.equals(equipmentInfoAllVO.getTypeName(), EquipmentTypeConst.ElectricityEquipment.getValue())) {
                    //获取电费
                    EleFeeRuleResponseVo eleFeeRuleResponseVo = eleFeeRuleService.calculateOrderFee(equipmentInfoAllVO.getReadingValue() - equipmentInfoAllVO.getReadValue());
                    Double totalAmount = eleFeeRuleResponseVo.getTotalAmount();
                    dormitoryExpenseBill.setElectricityExpense(totalAmount);
                }
            }
            //设置总花费
            dormitoryExpenseBill.setTotalExpense(dormitoryExpenseBill.getElectricityExpense()+dormitoryExpenseBill.getWaterExpense());
            dormitoryExpenseBill.setBillDate(new Date());
            dormitoryExpenseBills.add(dormitoryExpenseBill);
        }
        //保存账单
        dormitoryExpenseBillService.saveBatch(dormitoryExpenseBills);

        log.info("开始执行月末设备数据更新任务");
        try {
            // 1. 获取所有设备数据
            List<EquipmentData> equipmentDataList = equipmentDataService.list();
            for (EquipmentData equipmentData : equipmentDataList) {
                // 2. 获取每个设备最新的历史读数
                QueryWrapper<ReadingHistory> queryWrapper = new QueryWrapper<>();
                queryWrapper.eq("equipmentId", equipmentData.getEquipmentId())
                        .orderByDesc("createTime")
                        .last("LIMIT 1");
                ReadingHistory latestHistory = readingHistoryMapper.selectOne(queryWrapper);
                if (latestHistory != null) {
                    log.info("计算花费，更新额度");
                    EquipmentDataVO equipmentDataVO = equipmentDataService.getEquipmentDataVO(equipmentData, null);
                    if(Objects.equals(equipmentDataVO.getEquipmentInfoVO().getTypeName(), EquipmentTypeConst.WaterEquipment.getValue())) {
                        WaterFeeRuleResponseVo waterFeeRuleResponseVo = waterFeeRuleService.calculateOrderFee(latestHistory.getReadingValue() - equipmentData.getReadValue());
                        Double totalAmount = waterFeeRuleResponseVo.getTotalAmount();
                        equipmentData.setEquipmentBalance(equipmentData.getEquipmentBalance() - totalAmount);
                    }
                    else if(Objects.equals(equipmentDataVO.getEquipmentInfoVO().getTypeName(), EquipmentTypeConst.ElectricityEquipment.getValue())){
                        EleFeeRuleResponseVo eleFeeRuleResponseVo = eleFeeRuleService.calculateOrderFee(latestHistory.getReadingValue() - equipmentData.getReadValue());
                        Double totalAmount = eleFeeRuleResponseVo.getTotalAmount();
                        equipmentData.setEquipmentBalance(equipmentData.getEquipmentBalance() - totalAmount);
                    }
                    // 3. 更新设备数据的读数值
                    log.info("更新设备数据的读数值");
                    equipmentData.setReadValue(latestHistory.getReadingValue());
                    equipmentDataService.updateById(equipmentData);
                }
            }
            log.info("月末设备数据更新任务执行完成");
        } catch (Exception e) {
            log.error("月末设备数据更新任务执行失败", e);
        }
    }
    //每天早上四点生成当天的余额报警记录
    @Scheduled(cron = "0 0 1 * * ?")
    public void createBalanceWarning() {
        log.info("开始执行余额报警记录生成任务");
        //获取水电最低值
        List<BalanceWarning> balanceWarnings=balanceWarningService.list();
        Double water=(double)0, electricity= (double) 0;
        for (BalanceWarning balanceWarning : balanceWarnings) {
            if(balanceWarning.getWarningType().equals(EquipmentNameConst.WATER)){
                water=balanceWarning.getThresholdValue();
            }else if(balanceWarning.getWarningType().equals(EquipmentNameConst.ELECTRICITY)){
                electricity=balanceWarning.getThresholdValue();
            }
        }
        System.out.println("water"+water);
        System.out.println("electricity"+electricity);
        //获取所有设备数据
        List<EquipmentInfoAllVO> equipmentInfoAllVOS=equipmentInfoMapper.getEquipmentInfoAll();
        log.info("添加集合");
        List<BalanceAlarm> balanceAlarms=new ArrayList<>();
        for (EquipmentInfoAllVO equipmentInfoAllVO : equipmentInfoAllVOS) {
            System.out.println("begin");
            if (Objects.equals(equipmentInfoAllVO.getTypeName(), EquipmentTypeConst.WaterEquipment.getValue())) {
                //获取水费
                WaterFeeRuleResponseVo waterFeeRuleResponseVo = waterFeeRuleService.calculateOrderFee(equipmentInfoAllVO.getReadingValue() - equipmentInfoAllVO.getReadValue());
                Double totalAmount = waterFeeRuleResponseVo.getTotalAmount();
                if(equipmentInfoAllVO.getEquipmentBalance() - totalAmount < water){
                    Double yuE=equipmentInfoAllVO.getEquipmentBalance() - totalAmount;
                    BalanceAlarm balanceAlarm=new BalanceAlarm();
                    balanceAlarm.setDormitoryId(equipmentInfoAllVO.getDormitoryId());
                    balanceAlarm.setEquipmentId(equipmentInfoAllVO.getEquipmentId());
                    balanceAlarm.setDeviceBalance(yuE);
                    balanceAlarm.setNote("水费余额不足请至少充值"+(water-yuE)+"元");
                    balanceAlarm.setIsSolved(0);
                    balanceAlarm.setAlarmDate(new Date());
                    balanceAlarms.add(balanceAlarm);
                }
            } else if (Objects.equals(equipmentInfoAllVO.getTypeName(), EquipmentTypeConst.ElectricityEquipment.getValue())) {
                //获取电费
                EleFeeRuleResponseVo eleFeeRuleResponseVo = eleFeeRuleService.calculateOrderFee(equipmentInfoAllVO.getReadingValue() - equipmentInfoAllVO.getReadValue());
                Double totalAmount = eleFeeRuleResponseVo.getTotalAmount();
                System.out.println("total"+totalAmount);
                System.out.println("equipmentInfoAllVO.getEquipmentBalance()"+equipmentInfoAllVO.getEquipmentBalance());
                if(equipmentInfoAllVO.getEquipmentBalance() - totalAmount < electricity){
                    Double yuE=equipmentInfoAllVO.getEquipmentBalance() - totalAmount;
                    BalanceAlarm balanceAlarm=new BalanceAlarm();
                    balanceAlarm.setDormitoryId(equipmentInfoAllVO.getDormitoryId());
                    balanceAlarm.setEquipmentId(equipmentInfoAllVO.getEquipmentId());
                    balanceAlarm.setDeviceBalance(yuE);
                    balanceAlarm.setAlarmDate(new Date());
                    balanceAlarm.setNote("电费余额不足请至少充值"+(electricity-yuE)+"元");
                    balanceAlarm.setIsSolved(0);
                    balanceAlarms.add(balanceAlarm);
                }
            }
        }
        balanceAlarmService.saveBatch(balanceAlarms);
    }
}

